local skynet = require "skynet"
local log = require "sky_log"
local serpent = require "serpent"
local httpc = require "http.httpc"

local M = {}

--============================= Normal Function =============================--
--ts转date
M.ts2date = function (ts)
	return os.date("%Y-%m-%d %H:%M:%S", ts)
end

--date转ts
M.data2ts = function (date)
	local n1,n2,n3 = string.match(date, "(%d+)-(%d+)-(%d+)")
	--print(n1) print(n2) print(n3)
	return os.time({year=n1, month=n2,day=n3, hour=0, min=0, sec=0})
end

--当月总天数计算
M.get_month_days = function()
	local year = os.date("%Y", os.time())
	local month = os.date("%m", os.time()) + 1	-- 获取天数的目标月份需要+1
	local month_days = os.date("%d", os.time({year = year, month = month, day = 0}))  -- day为0则表示上个月的最后一天

	return month_days
end

--获取当天0点时间戳
M.get_day_zero = function(ts)
	--取年月日， 时分秒给0，即得当天0点时间戳
	local ts_table = os.date("*t", ts)
	local zero_ts = os.time({year=ts_table.year, month=ts_table.month, day=ts_table.day,
		hour=0, min=0, sec=0})

	return zero_ts
end

--获取当天23:59:59点时间戳
M.get_day_last = function(ts)
	if not ts then
		ts = os.time()
	end

	--取年月日， 时分秒给0，即得当天0点时间戳
	local ts_table = os.date("*t", ts)
	local zero_ts = os.time({year=ts_table.year, month=ts_table.month, day=ts_table.day,
		hour=23, min=59, sec=59})

	return zero_ts
end

--获取当周0点时间戳
M.get_week_zero = function(ts)
	local ONE_DAY_HOUR = 24               --一天24小时
	local ONE_HOUR_SEC = 3600             --一小时3600秒
	local RESET_SUNDAY = 1                --周日复位时，时间函数里的wday要减1
	--!*t格林威治时间  *t当前时区时间
	local ts_table = os.date("*t", ts)
	local day_zero_ts = os.time({year=ts_table.year, month=ts_table.month, day=ts_table.day,
		hour=0, min=0, sec=0})

	local week_zero_ts = day_zero_ts - (ts_table.wday-RESET_SUNDAY)*ONE_DAY_HOUR*ONE_HOUR_SEC

	return week_zero_ts
end

--文本化输出打印数据
function M.write_read_file(body, file_name)
	if not file_name then
		file_name = "write_read_file_"
	end

    local now_date = os.date( "%Y%m%d",  os.time() )
    local f = io.open("./log/"..file_name..now_date..".lua", "w+")
    if f then 
        f:write("info=", serpent.block(body))
        f:close()
    end
end

--table赋值
function M.clone_table(src_t)
	local des_t = {}
	for k, v in pairs(src_t or {}) do
        if type(v) == "table" then
            des_t[k] = M.clone_table(v)
        else
            des_t[k] = v
        end
    end
    return des_t
end

--table转string
function M.table2string(t)
	local mark={}
	local assign={}

	local function ser_table(tbl,parent)
		mark[tbl]=parent
		local tmp={}
		for k, v in pairs(tbl) do
			local key= type(k)=="number" and "["..k.."]" or "[".. string.format("%q", k) .."]"
			if type(v)=="table" then
				local dotkey= parent .. key
				if mark[v] then
					table.insert(assign, dotkey .. "=" .. mark[v] .. "")
				else
					table.insert(tmp, key .. "=" .. ser_table(v,dotkey))
				end
			elseif type(v) == "string" then
				table.insert(tmp, key .. "=" .. string.format('%q', v))
			elseif type(v) == "number" or type(v) == "boolean" then
				table.insert(tmp, key .. "=" .. tostring(v))
			end
		end
		return "{" .. table.concat(tmp,",") .. "}"
	end

	return ser_table(t,"ret") .. table.concat(assign, "")
end

-----------------------------------------------------------------------------------------
--检查table中是否含有function
-----------------------------------------------------------------------------------------
function M.var_dump_has_func(t, level)
	if  not t then
		return false
	end

	if  level and level >= 8 then
		return true; -- 无限循环保护
	end

	local lv = level or 0

	for k, v in pairs( t ) do
		if type(v) == 'function' then
			return true
		elseif  type(v) == 'table'    then
			if  M.var_dump_has_func( v, lv+1 ) then
				return true
			end
		else
			--nothing
		end
	end
	return false
end

-----------------------------------------------------------------------------------------
--安全的把一个string转换成lua的table [有个坑注意下： "123,456"===>转换会报错 table.loadstring只会得到123
-----------------------------------------------------------------------------------------
function M.safe_loadstring( txt, no_check_safe )
	local ret = {};

	local config_ = 'do local _local_var_ =\n' .. txt ..  '\nreturn	_local_var_; end';
	--log.debug( "-----------------------------------------" );
	--log.debug( config_ );
	--log.debug( "-----------------------------------------" );

	local need_check_function = false;  --需要检测function

	if  no_check_safe == true then
		--不用检查括号安全
	else
		if  string.find( txt, '%(' ) or  string.find( txt, '%)' )  then
			need_check_function = true
		end
	end

	--local func = loadstring( config_ );
	--skynet用的lua 5.3，loadstring不再可用，改为load
	local func = load( config_ )	
	--log.debug( log.fast() and "safe load type=" .. type(func) );

	if func and type(func) == 'function' then
		ret = func()
		--log.debug("ret=", ret)
		--log.debug("type(ret)=", type(ret))
		if ret and type(ret) == 'table' then
			--log.debug( "table====================================" );
			--log.debug( table.tostring(ret) );
			--log.debug( "table====================================" );
			--M.var_dump( ret );

			if need_check_function then
				local has_ = M.var_dump_has_func( ret )
				if  has_ then
					log.error( "find '(' or ')' and functions in config ================ ERROR config " )
					return {}
				else
					log.debug("NORMAL: find '(' or ')', but no functions in config." )
				end
			end

		else
			--log.error("table data error");
			return nil
		end
	end

	return ret or {}
end

-----------------------------------------------------------------------------------------
--接口函数	: base64_url2std
--将url中传输的base64 string 转成标准的base64
--标准base64中，有几个字符是保留字: [ + / = ] 无法放在url中，
--客户端对此进行了转换，现在转回来
-----------------------------------------------------------------------------------------
function M.base64_url2std( str64_ )
	local s_ = string.gsub(str64_,"-","+")
		  s_ = string.gsub(s_    ,";","/")
		  s_ = string.gsub(s_    ,"_","=")
	return s_
end

function M.encodeURI(s)
    if not s then
        return ''
    end
    s = string.gsub(s, "([^%w%.%- ])", function(c) return string.format("%%%02X", string.byte(c)) end)
    return string.gsub(s, " ", "+")
end

--发起http请求
function M.http_request(host, url, info, recvheader, header, content)
	local urlinfo = '/?cmd='..url
	if info and type(info)=='table' then 
		for k, v in pairs(info) do
			urlinfo = urlinfo.. '&'..k .. '=' .. v 
		end
	end
	--host="10.0.6.40:1301"
	--urlinfo = "/?cmd=report_enter_game&room_id=2222&player_id=12345&room_level=1&game_type=25&table_id=3333"
	local status, ret = httpc.request("GET", host, urlinfo, recvheader, header, content)
	--log.info("status=", status)
	--log.info("ret=", ret)
	if status ~= 200 then
        if status >= 400 then
            log.error('send http_request faild, url is :', host..url..' status:'..status..'  error is'..ret)
            return false, ret
        else
            log.warning('send http_request may redirect, status: '..status..'  ret is '..ret)
            return true, ret
        end
    else
		--log.info("ret=", ret)
        return true, ret
    end
end

function M.debug_logic(body)
    if __LOG_LEVEL___ > 1 then
        return
    end
    local debug_logic_flag = tonumber(skynet.getenv("debug_logic_flag"))
    if not debug_logic_flag 
    or debug_logic_flag < 1
    or not body then
        return
    end

    local title = "debug_logic: "
    local source = debug.getinfo(2).source
    local currentline = debug.getinfo(2).currentline
    skynet.error("LIGHT_GREEN;"..source..":"..currentline.."; ".."[INFO]  "..title..serpent.block(body))
end

function M.delay_times(min, max)
    local delay_times_n = tonumber(skynet.getenv("delay_times_n"))
    if not delay_times_n
    or delay_times_n < 1 then
        return
    end

	local n_time
    if not min then
        n_time = math.random(60, 200)
	end

	if min and
	not max then
		n_time = min
	end

	if min and max then
		n_time = math.random(min, max)
	end

    skynet.sleep(n_time)
end

--============================= Puke Function =============================--
--无花色记录表 (enemy_no_color_t/friend_no_color_t) 
--no_color_t = {[color] = true[无该花色 or nil[有该花色]] 
--handcards: {[1]=card_1, [2]=card_2} 可 ipairs遍历连续的
--outcard_history: {[1]=card_1, [2]=card_2} 可 ipairs遍历连续的
--[[
outcard_history_more: {
	--第几回合
	[round] = {
		--出牌次序
		[outcard_seq] = {
			seatid   --出牌座位号
			outcard  --出的牌
		} 
	}
}
--]]

function M.boyaa_get_seatid(max_player, already_sit_t, table_type)
	local boyaa_seat_state = {
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 1, 0, 1, 0, 0, 0 },
		{ 0, 1, 0, 0, 1, 0, 0, 1, 0 },
		{ 1, 0, 0, 1, 0, 1, 0, 0, 1 },
		{ 0, 0, 1, 1, 1, 1, 1, 0, 0 },
		{ 1, 0, 1, 1, 0, 1, 1, 0, 1 },
		{ 0, 1, 1, 1, 1, 1, 1, 1, 0 },
		{ 1, 1, 1, 1, 0, 1, 1, 1, 1 },
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1 }
	}
	local tmp_t = {}
	local game_seats_info = boyaa_seat_state[max_player]
	
	for k, v in ipairs(game_seats_info) do
		if v==1 then
			table.insert(tmp_t, k)
		end
	end

	if table_type and table_type==TABLE_TYPE.TARNEEB then
		for _, v in pairs(already_sit_t) do
			tmp_t[v] = 0
		end
	else
		for _, v in pairs(already_sit_t) do
			for k, pos in pairs(tmp_t) do
				if v==pos then
					tmp_t[k] = 0
				end
			end
		end
	end

	for _, v in ipairs(tmp_t) do
		if v~=0 then
			return v
		end
	end
end

--计算牌值
function M.calc_card_value(card)
	assert(card)
    return tonumber((card) & 0xff)
end

--计算花色
function M.calc_card_color(card)
	assert(card)
    return tonumber((card) >> 8)
end

--洗牌
function M.rand_cards(the_cards_t)
    for k, v in pairs(the_cards_t) do
        local index = math.random(1, #the_cards_t)
        local temp = the_cards_t[k]
        the_cards_t[k] = the_cards_t[index]
        the_cards_t[index] = temp
    end
    --再洗一次
    for k, v in pairs(the_cards_t) do
        local index = math.random(1, #the_cards_t)
        local temp = the_cards_t[k]
        the_cards_t[k] = the_cards_t[index]
        the_cards_t[index] = temp
    end
end

--根据花色牌点得到具体牌值
function M.get_card_by_color_and_value(color, value)
	assert(color)
	assert(value)
    color = tonumber( (color) ) << 8
	return (color + tonumber(value))
end

--得到自己手中某花色牌数量 [1方块 2梅花 3红桃 4黑桃]
function M.get_color_cards_count(handcards, the_color)
    local count = 0

    for _, v in pairs(handcards or {}) do
        if M.calc_card_color(v)==the_color then 
            count = count + 1
        end
    end

    return count
end

--得到手牌中对应花色的牌table
function M.get_handcards_one_color(handcards, the_color)
	local color
	local t = {}
	for _, v in pairs(handcards) do
		color = M.calc_card_color(v)
		if color==tonumber(the_color) then 
			table.insert(t, v)
		end
	end

	return t
end

--得到手中某花色最大的牌
function M.get_color_max_card(handcards, color)
    local t = {}

	for _, v in pairs(handcards) do
		local _color = M.calc_card_color(v)
		if _color==color then
			table.insert(t, v)
		end
	end

	table.sort(t, function (a, b)
		return a < b
	end)

	return t[#t]
end

--得到某花色中等偏大 (第二大) 的牌
function M.get_color_middle_card(handcards, color)
    local t = {}

	for _, v in pairs(handcards) do
		local _color = M.calc_card_color(v)
		if _color==color then
			table.insert(t, v)
		end
	end

	table.sort(t, function (a, b)
		return a < b
	end)

	local index = #t
	if index==0 then 
		log.error("do_out_color_middle_card no color handcards:", color.."|"..serpent.block(handcards))
	end

	if index==1 then 
		return t[index]
	end

	return t[index-1]
end

--得到某花色最小的牌
function M.get_color_min_card(cards_t, color)
    local t = {}

	for _, v in pairs(cards_t) do
		local _color = M.calc_card_color(v)
		if _color==color then
			table.insert(t, v)
		end
	end

	table.sort(t, function (a, b)
		return a < b
	end)
	
	return t[1]
end

--得到手中花色最少的最大牌
function M.get_handcards_less_color_max_card(handcards)
	local color
	local count
	for i=1, 4 do
		local t = M.get_handcards_one_color(handcards, i)
		if #t > 0 then
			if not count then
				count = #t
				color = i
			end
			if count > #t then 
				count = #t
				color = i
			end
		end
	end

	local t2 = {}
	for _, v in pairs(handcards) do
		if M.calc_card_color(v)==color then 
			table.insert(t2, v)
		end
	end

	table.sort(t2, function (a, b)
		return a>b
	end)

	return t2[1]
end

--得到花色数量多的最小牌
function M.get_more_color_min_card(handcards)
	local color = M.get_handcards_more_color(handcards)

	local t2 = {}
	for _, v in pairs(handcards) do
		if M.calc_card_color(v)==color then 
			table.insert(t2, v)
		end
	end

	table.sort(t2, function (a, b)
		return a < b
	end)

	return t2[1]
end

--得到花色数量多的最大牌
function M.get_more_color_max_card(handcards)
	local color = M.get_handcards_more_color(handcards)

	local t2 = {}
	for _, v in pairs(handcards) do
		if M.calc_card_color(v)==color then 
			table.insert(t2, v)
		end
	end

	table.sort(t2, function (a, b)
		return a > b
	end)

	return t2[1]
end

--得到手中花色最多的 那个花色
function M.get_handcards_more_color(handcards)
	local color
	local count
	for i=1, 4 do
		local t = M.get_handcards_one_color(handcards, i)
		if #t > 0 then
			if not count then
				count = #t
				color = i
			end
			if count < #t then 
				count = #t
				color = i
			end
		end
	end

	return color
end

--检测某张牌是否在手中
function M.check_card_in_handcards(handcards, the_card)
	for _, v in pairs(handcards) do
		if v==the_card then 
			return true
		end
	end

	return false
end

--检测出牌历史 并从手牌中得到一张 花色出的最多的某花色牌。 无则返回nil
function M.history_check_more_color_card(handcards, outcard_history)
	local color_t = {}

	for i=1, 4 do
		local temp = {}
		temp.color = i
		temp.count = 0
		color_t[i] = temp
	end

	local color
	for _, v in pairs(outcard_history or {}) do
		color = M.calc_card_color(v)
		color_t[color].count = color_t[color].count + 1
	end
 
	table.sort(color_t, function (a, b)
		return a.count>b.count
	end)


	local ret_cards_t = {}
	for _, v in ipairs(color_t) do
		for _, card in ipairs(handcards) do
			color = M.calc_card_color(card)
			if color==v.color then
				if not ret_cards_t[v.color] then
					ret_cards_t[v.color] = {}
					ret_cards_t[v.color].color_count = v.count
					ret_cards_t[v.color].min_card = card
				end
			end
		end
	end

	local the_color, max_color_count
	for i=1, 4 do
		if ret_cards_t[i] then
			if the_color==nil then
				the_color = i
				max_color_count = ret_cards_t[i].color_count
			else
				if max_color_count<ret_cards_t[i].color_count then
					the_color = i
					max_color_count = ret_cards_t[i].color_count
				elseif max_color_count==ret_cards_t[i].color_count then
					local k1 = M.calc_card_value(ret_cards_t[the_color].min_card)
					local k2 = M.calc_card_value(ret_cards_t[i].min_card)
					if k1 > k2 then
						the_color = i
						max_color_count = ret_cards_t[i].color_count
					end
				end
			end
		end
	end

	local card = ret_cards_t[the_color].min_card
	return card
end

--检测出牌历史 并从手牌中得到一张 花色出的最少的某花色牌。 无则返回nil
function M.history_check_less_color_card(handcards, outcard_history)
	local color_t = {}

	for i=1, 4 do
		local temp = {}
		temp.color = i
		temp.count = 0
		color_t[i] = temp
	end

	local color
	for _, v in pairs(outcard_history or {}) do
		color = M.calc_card_color(v)
		color_t[color].count = color_t[color].count + 1
	end
	table.sort(color_t, function (a, b)
		return a.count < b.count
	end)

	for _, v in ipairs(color_t) do
		for _, card in ipairs(handcards) do
			color = M.calc_card_color(card)
			if color==v.color then
				return card
			end
		end
	end
end

--检测出牌历史并从手牌中得到一张 花色出的最少的牌（若花色均一样则出手里牌点数最小的）
function M.history_check_less_color_or_min_card(handcards, outcard_history)
	local t = M.clone_table(handcards)
	table.sort(t, function (a, b)
		return a < b
	end)

	local card = M.history_check_less_color_card(t, outcard_history)

	return card
end

--根据牌桌已出的牌检测 某个 check_cards_t集合内 是否有某花色的最大扑克牌 (A为14),并返回其点数。 否则返回 nil 
function M.history_check_max_card(check_cards_t, the_color, outcard_history)
	local flag_t = {}
	for i=1, 14 do
		table.insert(flag_t, false)
	end
 
	--已出的牌取该花色
	local color, value, max_handcands_value
	for _, v in pairs(outcard_history or {}) do
		color = M.calc_card_color(v) 
		if color==the_color then 
			value = M.calc_card_value(v)
			flag_t[value] = true
		end
	end

	--被检测的cards集合内取该花色
	for _, v in pairs(check_cards_t or {}) do
		color = M.calc_card_color(v)
		if color==the_color then 
			value = M.calc_card_value(v)
			flag_t[value] = true
			if not max_handcands_value then 
				max_handcands_value = value
				if max_handcands_value==14 then 
					return 14
				end
			end
			if max_handcands_value < value then
				max_handcands_value = value
			end
			
		end
	end

	if max_handcands_value==nil then 
		return nil
	end
 
	for index=14, 1, -1 do
		if flag_t[index]==false then 
			if index>max_handcands_value then 
				return nil
			elseif index<value then 
				break
			end
		end
	end
	
	return max_handcands_value
end

--根据牌桌已出的牌检测某个 check_cards_t集合内是否有某花色的第二大扑克牌 (A为14),并返回其点数。 否则返回 nil 
function M.history_check_second_card(check_cards_t, the_color, outcard_history)
	local flag_t = {}
	for i=1, 14 do
		table.insert(flag_t, false)
	end
 
	--已出的牌取该花色
	local color, value
	for _, v in pairs(outcard_history or {}) do
		color = M.calc_card_color(v) 
		if color==the_color then 
			value = M.calc_card_value(v)
			flag_t[value] = true
		end
	end
 
	local handcards_color_t = {}
	--手牌取该花色
	for _, v in pairs(check_cards_t) do
		color = M.calc_card_color(v)
		if color==the_color then 
			value = M.calc_card_value(v)
			table.insert(handcards_color_t, v)
		end
	end
	table.sort(handcards_color_t, function (a, b)
		return a>b
	end)

	if #handcards_color_t==0 then
		return
	end

	local card = handcards_color_t[1]
	local max_second_value = M.calc_card_value(card)
	local count = 0

	for index=14, 1, -1 do
		if flag_t[index]==false then 
			if index>max_second_value then 
				count = count + 1
			elseif index<max_second_value then 
				break
			end
		end
	end

	if count ~= 1 then 
		return
	end
 
	return card
end

--结合出牌历史： 检测某张牌是否目前牌桌上最大了
function M.history_check_the_max_card(handcards, outcard_history, the_card)
	local tmp_t = M.clone_table(outcard_history)
	local color = M.calc_card_color(the_card)

	--手牌也当作已出的牌
	local the_color
	for _, v in pairs(handcards) do
		the_color = M.calc_card_color(v)
		if color==the_color then 
			table.insert(tmp_t, v)
		end
	end

	local card = M.history_check_max_card({the_card}, color, tmp_t)
	if card then 
		return true
	end
	
	return false
end

--历史出牌中：某花色牌出过几次
function M.history_check_color_out_count(outcard_history, color)
	local count = 0
    local the_color
	for _, v in pairs(outcard_history) do
		the_color = M.calc_card_color(v)
		if color==the_color then 
			count = count + 1
		end
	end

	return count
end

--历史出牌中：某花色牌出过几回合
function M.history_check_color_out_round(outcard_history_more, color)
	local color_count_t = {0, 0, 0, 0}

	local the_color
	for _, v in pairs(outcard_history_more) do
        local find_color_t = {}
        for _, value in pairs(v) do
            the_color = M.calc_card_color(value.outcard)
            find_color_t[the_color] = true
        end

        for color, _v in pairs(find_color_t) do
            color_count_t[color] = color_count_t[color] + 1
        end
    end

	return color_count_t[color]
end

--根据历史出牌 得到手中花色出的最少的最大牌（若花色均一样则出手里牌点数最大的）
function M.history_check_less_color_max_card(handcards, outcard_history)
	local t = M.clone_table(handcards)
	table.sort(t, function (a, b)
		return a > b
	end)

	local card = M.history_check_less_color_card(t, outcard_history)
	
	return card
end

--结合历史出牌: 是否目前剩下的某花色牌是否全在手中
function M.history_check_has_all_color_card(handcards, main_color, outcard_history)
	local t = {}
    local color, value
	--手牌
	for _, v in pairs(handcards) do
		color = M.calc_card_color(v)
		value = M.calc_card_value(v)
		if color==main_color then 
			t[value] = true
		end
	end
	--历史出牌
	for _, v in pairs(outcard_history) do
		color = M.calc_card_color(v)
		value = M.calc_card_value(v)
		if color==main_color then 
			t[value] = true
		end
	end
	
	for i=1, 14 do
		if t[i]~=true then 
			return false
		end
	end

	return true
end

--检测某花色未出的牌是哪些
function M.history_check_color_left_cards_t(handcards, the_color, outcard_history)
	local t = {}

	local value
    for _, v in pairs(handcards) do
        if M.calc_card_color(v)==the_color then 
            value = M.calc_card_value(v)
			t[value] = true
        end
    end

	for _, v in pairs(outcard_history) do
        if M.calc_card_color(v)==the_color then 
            value = M.calc_card_value(v)
			t[value] = true
        end
    end

	local ret_t = {}
	for i=2, 14 do
		if t[i]==nil then 
			table.insert(ret_t, i)
		end
	end

    return ret_t
end

--检测某花色还有几张没出
function M.history_check_color_left_cards_count(handcards, the_color, outcard_history)
	local t = M.history_check_color_left_cards_t(handcards, the_color, outcard_history)

	return (#t)
end

--某花色剩余未出的那张牌： (可获取最后仅剩的那张)
function M.history_check_color_the_last_card(handcards, the_color, outcard_history)
	local t = M.history_check_color_left_cards_t(handcards, the_color, outcard_history)

	local card = M.get_card_by_color_and_value(the_color, t[1])
	
	return card
end

--是否某种花色第一、二轮出牌
function M.history_check_color_first_out(outcard_history_more, handcards)
	local color_count_t = {0, 0, 0, 0}

	local the_color
	for _, v in pairs(outcard_history_more) do
        local find_color_t = {}
		if v and v[1] and v[1].outcard then
            the_color = M.calc_card_color(v[1].outcard)
            find_color_t[the_color] = true
        end

        for color, _v in pairs(find_color_t) do
            color_count_t[color] = color_count_t[color] + 1
        end
    end

	local ret_t = {}
	for i=1, 4 do
		if color_count_t[i]<2 then
			table.insert(ret_t, i)
		end
	end

	for k, v in pairs(ret_t) do
		local n = M.get_color_cards_count(handcards, v)
		if n==0 then
			ret_t[k] = nil
		end
	end

	return ret_t
end

--是否有某种花色是第3轮出牌
function M.history_check_color_third_out(outcard_history_more, handcards)
	local color_count_t = {0, 0, 0, 0}

	local the_color
	for _, v in pairs(outcard_history_more) do
        local find_color_t = {}
        if v and v[1] and v[1].outcard then
            the_color = M.calc_card_color(v[1].outcard)
            find_color_t[the_color] = true
        end

        for color, _v in pairs(find_color_t) do
            color_count_t[color] = color_count_t[color] + 1
        end
    end

	local ret_t = {}
	for i=1, 4 do
		if color_count_t[i]==2 then
			table.insert(ret_t, i)
		end
	end

	for k, v in pairs(ret_t) do
		local n = M.get_color_cards_count(handcards, v)
		if n==0 then
			ret_t[k] = nil
		end
	end

	return ret_t
end

--检测手牌中是否有比某张牌大的牌
function M.check_handcards_bigger_card(handcards, the_card, main_color)
	local color = M.calc_card_color(the_card)
	local value = M.calc_card_value(the_card)

	local _color, _value 
	--先比点数，有比 the_card大的就返回了
	for _, v in ipairs(handcards) do
		_color = M.calc_card_color(v)
		if _color==color then 
			_value = M.calc_card_value(v)
			if _value > value then 
				return true
			end
		end 
	end

	--再判断the_card是否非主牌, 非主牌时手里任意一张主牌都大于该牌
	if color~=main_color then 
		for _, v in pairs(handcards) do
			_color = M.calc_card_color(v)
			if _color==main_color then 
				return true
			end
		end
	end

	return false
end

--检测手牌中是否有比某张牌大的牌并返回其中最小的牌
function M.check_handcards_bigger_card_min(handcards, the_card, main_color)
	local color = M.calc_card_color(the_card)
	local value = M.calc_card_value(the_card)

	local t = {}

	local _color, _value
	for _, v in ipairs(handcards) do
		_color = M.calc_card_color(v)
		if _color==color then 
			_value = M.calc_card_value(v)
			if _value > value then 
				table.insert(t, v)
			end
		end
	end

	if main_color then
		--优先比点数，没有大的再去找主牌
		if not next(t) and color~=main_color then
			for _, v in pairs(handcards) do
				_color = M.calc_card_color(v)
				if _color==main_color then 
					table.insert(t, v)
				end
			end
		end
	end

	table.sort(t, function (a, b)
		return a < b
	end)

	return t[1]
end

--检测手牌中是否有比某张牌大的牌并返回其中最大的的牌
function M.check_handcards_bigger_card_max(handcards, the_card, main_color)
	local color = M.calc_card_color(the_card)
	local value = M.calc_card_value(the_card)

	local t = {}

	local _color, _value
	for _, v in ipairs(handcards) do
		_color = M.calc_card_color(v)
		if _color==color then 
			_value = M.calc_card_value(v)
			if _value > value then 
				table.insert(t, v)
			end
		end
	end

	--[[
	--优先比点数，没有大的再去找主牌
	if not next(t) and color~=main_color then
		for _, v in pairs(handcards) do
			_color = M.calc_card_color(v)
			if _color==main_color then 
				table.insert(t, v)
			end
		end
	end
	--]]

	table.sort(t, function (a, b)
		return a > b
	end)

	return t[1]
end

--检测手牌中是否有比某张牌小的牌并返回其中最大的的牌(区分花色)
function M.check_handcards_small_card_max(handcards, the_card)
	local color = M.calc_card_color(the_card)
	local value = M.calc_card_value(the_card)

	local t = {}

	local max_value_card, max_value
	local _color, _value
	for _, v in ipairs(handcards) do
		_color = M.calc_card_color(v)
		_value = M.calc_card_value(v)

		if _color==color then 
			if _value < value then 
				table.insert(t, v)
			end
		else
			if max_value==nil then 
				max_value = _value
			end
			if max_value < _value then 
				max_value = _value
				max_value_card = v 
			end
		end

	end

	table.sort(t, function (a, b)
		return a > b
	end)

	return t[1] or the_card
end

--得到手牌中某个花色中除了某些牌点的牌table, [except_t是 牌点]
function M.get_cards_except_t(handcards, except_t, color)
	local t = {}

	local _color, _value, flag
	for _, v in pairs (handcards) do
		_color = M.calc_card_color(v)
		if _color==color then 
			flag = false
			_value = M.calc_card_value(v)
			for _, card_value in  pairs(except_t) do
				if _value==card_value then 
					flag = true
					break
				end
			end

			if flag==false then 
				table.insert(t, v)
			end
		end
	end

	table.sort(t, function (a, b)
		return a > b
	end)

	return t
end

--塔尼布检测是否出牌座位号是否队友 (固定4人，对位即队友) 同规则模式皆可使用该函数 
function M.check_is_friend(my_seatid, outcard_seatid)
	local MAX_PLAYER_TARNEEB = 4

    local friend_seat = (my_seatid + 2) % MAX_PLAYER_TARNEEB
    if friend_seat==0 then 
        friend_seat = 4
    end

    if friend_seat==tonumber(outcard_seatid) then 
        return true
    end

    return false
end

--根据自己的座位得到队友座位号(在固定4人，对位即队友模式下可通用)
function M.get_friend_seatid(my_seatid)
	local MAX_PLAYER_TARNEEB = 4

    local friend_seat = (my_seatid + 2) % MAX_PLAYER_TARNEEB
	if friend_seat==0 then 
        friend_seat = 4
    end

	return friend_seat
end

return M